import { BaseService } from '../framework/base-service.js'
import _ from 'lodash'

/**
 * BWS Service - 业务层 WebSocket 服务
 * 处理具体的业务逻辑，基于核心 WebSocketManager
 */
export default class BWSService extends BaseService {
  static metadata = {
    name: 'bws',
    dependencies: ['cache'],  // 依赖缓存服务
    singleton: true
  }
  
  constructor(cache) {
    super()
    this.cache = cache
  }
  
  async onInit() {
    this.setupEventMappings()
    this.setupMessageHandlers()
    this.setupMiddleware()
    this.logger.info('BWSService', '✅ BWS service initialized')
  }
  
  setupEventMappings() {
    // 监听业务数据变化事件
    const dataTypes = [
      'amb', 'ambstatus', 'emtstatus', 'ambtask', 'emttask',
      'center', 'station', 'hospital', 'aed', 'fivekind', 
      'emt', 'rp', 'accepts', 'tasks', 'cltasks', 'online'
    ]
    
    _(dataTypes).forEach(type => {
      ['created', 'updated', 'deleted', 'calculated'].forEach(action => {
        this.eventBus.on(`${action}:biz.${type}`, (data) => {
          // 广播给所有订阅了该事件的客户端
          this.wsManager.broadcastToRoom(`biz.${type}`, `${action}:biz.${type}`, data)
        })
      })
    })
    
    // BSS 事件转发
    this.eventBus.on('bss:*', (event, data) => {
      this.wsManager.broadcastToRoom('bss', event, data)
    })
    
    // 刷新完成事件
    this.eventBus.on('refresh:completed', ({ task, result }) => {
      this.wsManager.broadcast('refresh:completed', { task, result })
    })
  }
  
  setupMessageHandlers() {
    const ws = this.wsManager
    
    // ping/pong 心跳
    ws.on('ping', (clientId, data) => {
      const client = ws.getClient(clientId)
      if (client) {
        client.data.lastPing = Date.now()
        ws.send(clientId, 'pong', { timestamp: Date.now() })
      }
    })
    
    // 订阅房间
    ws.on('subscribe', (clientId, data) => {
      const room = data.room || data.event
      if (room) {
        ws.join(clientId, room)
        ws.send(clientId, 'subscribed', { room })
        this.logger.debug('BWSService', `Client ${clientId} subscribed to ${room}`)
      }
    })
    
    // 退订房间
    ws.on('unsubscribe', (clientId, data) => {
      const room = data.room || data.event
      if (room) {
        ws.leave(clientId, room)
        ws.send(clientId, 'unsubscribed', { room })
        this.logger.debug('BWSService', `Client ${clientId} unsubscribed from ${room}`)
      }
    })
    
    // 处理命令
    ws.on('command', async (clientId, data) => {
      await this.handleCommand(clientId, data.event, data.data)
    })
    
    // RPC 调用
    ws.on('call', async (clientId, data) => {
      await this.handleRPCCall(clientId, data)
    })
    
    // Socket.io 兼容性消息
    ws.on('2', (clientId, message) => {
      this.handleSocketIOMessage(clientId, message)
    })
  }
  
  setupMiddleware() {
    // 认证中间件
    this.wsManager.use(async (clientId, event, data, ws) => {
      // 某些事件不需要认证
      const publicEvents = ['ping', 'connect', 'authenticate']
      if (publicEvents.includes(event)) {
        return true
      }
      
      // 检查客户端是否已认证
      const client = ws.getClient(clientId)
      if (!client?.data?.authenticated) {
        ws.send(clientId, 'error', { message: 'Not authenticated' })
        return false
      }
      
      return true
    })
    
    // 日志中间件
    this.wsManager.use(async (clientId, event, data) => {
      this.logger.debug('BWSService', `Message from ${clientId}: ${event}`)
      return true
    })
  }
  
  async handleCommand(clientId, event, data) {
    // 处理各种命令
    switch (event) {
      case 'authenticate':
        await this.authenticate(clientId, data)
        break
        
      case 'query':
        await this.handleQuery(clientId, data)
        break
        
      case 'exec':
        await this.handleExec(clientId, data)
        break
        
      case 'cache.get':
        await this.handleCacheGet(clientId, data)
        break
        
      case 'cache.set':
        await this.handleCacheSet(clientId, data)
        break
        
      default:
        // 转发给事件总线
        this.eventBus.emit(`ws:${event}`, { clientId, data })
    }
  }
  
  async authenticate(clientId, data) {
    // 简单的认证逻辑
    const { token, user } = data
    const client = this.wsManager.getClient(clientId)
    
    if (client) {
      client.data.authenticated = true
      client.data.user = user
      client.data.token = token
      
      // 自动加入用户房间
      this.wsManager.join(clientId, `user:${user}`)
      
      this.wsManager.send(clientId, 'authenticated', { 
        success: true, 
        user,
        timestamp: Date.now() 
      })
      
      this.logger.info('BWSService', `Client ${clientId} authenticated as ${user}`)
    }
  }
  
  async handleQuery(clientId, data) {
    const { namespace, key, sql } = data
    
    try {
      let result
      
      if (namespace && key) {
        // 从缓存查询
        result = await this.cache.get(namespace, key)
      } else if (sql) {
        // SQL 查询（需要 rdb 服务）
        const rdb = await this.app.container.get('rdb')
        result = await rdb.execute(sql)
      }
      
      this.wsManager.send(clientId, 'query:result', { 
        success: true, 
        data: result,
        request: data 
      })
    } catch (error) {
      this.wsManager.send(clientId, 'query:error', { 
        success: false, 
        error: error.message,
        request: data 
      })
    }
  }
  
  async handleExec(clientId, data) {
    const { action, params } = data
    
    try {
      // 执行动作
      const result = await this.eventBus.emit(`action:${action}`, params)
      
      this.wsManager.send(clientId, 'exec:result', {
        success: true,
        action,
        result
      })
    } catch (error) {
      this.wsManager.send(clientId, 'exec:error', {
        success: false,
        action,
        error: error.message
      })
    }
  }
  
  async handleCacheGet(clientId, data) {
    const { namespace, key } = data
    
    try {
      const value = await this.cache.get(namespace, key)
      
      this.wsManager.send(clientId, 'cache:result', {
        namespace,
        key,
        value,
        found: value !== null
      })
    } catch (error) {
      this.wsManager.send(clientId, 'cache:error', {
        error: error.message
      })
    }
  }
  
  async handleCacheSet(clientId, data) {
    const { namespace, key, value, ttl } = data
    
    try {
      await this.cache.set(namespace, key, value, ttl)
      
      this.wsManager.send(clientId, 'cache:saved', {
        namespace,
        key,
        success: true
      })
    } catch (error) {
      this.wsManager.send(clientId, 'cache:error', {
        error: error.message
      })
    }
  }
  
  async handleRPCCall(clientId, data) {
    const { method, params, id } = data
    
    try {
      // 执行 RPC 调用
      let result
      
      // 根据方法路由到不同的服务
      const [service, action] = method.split('.')
      
      if (service === 'cache') {
        result = await this.cache[action](...params)
      } else if (service === 'biz') {
        result = await this.eventBus.emit(`rpc:${method}`, params)
      } else {
        throw new Error(`Unknown service: ${service}`)
      }
      
      this.wsManager.send(clientId, 'rpc:response', {
        id,
        result,
        success: true
      })
    } catch (error) {
      this.wsManager.send(clientId, 'rpc:response', {
        id,
        error: error.message,
        success: false
      })
    }
  }
  
  // Socket.io 兼容性处理
  handleSocketIOMessage(clientId, message) {
    try {
      // Socket.io v4 消息格式: ["event", data]
      const [event, ...args] = JSON.parse(message)
      
      // 转换为标准格式
      this.wsManager.handleMessage(clientId, JSON.stringify({
        event,
        data: args[0] || {}
      }))
    } catch (error) {
      this.logger.warn('BWSService', `Invalid Socket.io message from ${clientId}`)
    }
  }
  
  // 发送 Socket.io 格式的消息
  sendSocketIO(clientId, event, data) {
    const client = this.wsManager.getClient(clientId)
    if (client) {
      // Socket.io v4 格式
      const message = `42${JSON.stringify([event, data])}`
      client.ws.send(message)
    }
  }
  
  // 注册 API 路由
  registerRoutes(app) {
    // WebSocket 统计信息
    app.get('/api/ws/stats', c => {
      return c.json({
        ...this.wsManager.getStats(),
        service: 'bws'
      })
    })
    
    // 获取在线客户端
    app.get('/api/ws/clients', c => {
      const clients = this.wsManager.getAllClients().map(client => ({
        id: client.id,
        connectedAt: client.connectedAt,
        rooms: Array.from(client.rooms),
        authenticated: client.data?.authenticated || false,
        user: client.data?.user || null
      }))
      
      return c.json(clients)
    })
    
    // 向特定客户端发送消息
    app.post('/api/ws/send/:clientId', async c => {
      const clientId = c.req.param('clientId')
      const { event, data } = await c.req.json()
      
      const success = this.wsManager.send(clientId, event, data)
      
      return c.json({ success })
    })
    
    // 广播消息
    app.post('/api/ws/broadcast', async c => {
      const { event, data, room } = await c.req.json()
      
      let sent
      if (room) {
        sent = this.wsManager.broadcastToRoom(room, event, data)
      } else {
        sent = this.wsManager.broadcast(event, data)
      }
      
      return c.json({ sent })
    })
    
    return true
  }
}